Introdução
Nesse relatório será aplicado testes de hipótese para que possamos responder algumas perguntas (essas mesmas perguntas foram respondidas utilizando ICs aqui).
Antes de verificar os resultados obtidos, é importante que o leitor saiba o que significa e como interpretar o p-valor. O p-valor é a probabilidade de se obter uma estatística de teste igual ou mais extrema que aquela observada em uma amostra sob a hipótise nula, ou seja, um p-valor pequeno significa que a probabilidade de obter um valor da estatística de teste como o observado é muito improvável, levando assim à rejeição da hipótese nula.
Em um teste clássico de hipóteses, são definidas duas hipóteses, a nula (H0) e a alternativa (H1). Em muitas aplicações da estatística, convenciona-se definir a hipótese alternativa como a hipótese formulada pelo pesquisador, enquanto a hipótese nula é o seu complemento. A princípio, a hipótese nula é considerada a verdadeira.
No fim desse relatório, serão comparados os resultados obtidos aqui e os utilizando ICs.
Assim como no CP3, este relatório tem como objetivo analisar dados de commits no github. Utilizaremos uma amostra de dados da atividade global do github entre o período de 01/2016 e 05/2017. As linguagens que vamos analisar serão C++ e C# (duas das linguagens mais populares entre os programadores).
Primeiro, será feita a importação dos dados já com as linguagens de interesse filtradas. As variáveis que iremos utilizar serão the_year(o ano referente aos commits), the_month (o mês referente aos commits) e users (quantidade de usuários que fez commits).
dados_github = read_csv(here("data/github-users-committing-filetypes.csv"),
progress = FALSE,
col_types = cols(file_extension = col_character(),
month_day = col_integer(),
the_month = col_integer(),
the_year = col_integer(),
users = col_integer())) %>%
filter(file_extension %in% c("cpp", "cs"))
dados_cs = dados_github %>% filter(file_extension == "cs")
dados_cpp = dados_github %>% filter(file_extension == "cpp")
Antes de responder algumas perguntas, vamos dar uma olhada na linha do tempo das duas linguagens.
Ano de 2016
p =
dados_github %>%
filter(the_year == "2016") %>%
ggplot(aes(x=the_month,
y=users,
text = paste("Mês:",the_month,
"\nQuantidade de Usuários:",
users))) +
labs(y = "Quantidade de usuários", x = "Mês")+
theme(legend.position="none") +
geom_boxplot(fill = "#e99790") + facet_wrap( ~ file_extension)
ggplotly(p, tooltip = "text")
rm(p)
Ano de 2017
p =
dados_github %>%
filter(the_year == "2017") %>%
ggplot(aes(x=the_month,
y=users,
text = paste("Mês:",the_month,
"\nQuantidade de Usuários:",
users))) +
labs(y = "Quantidade de usuários", x = "Mês")+
theme(legend.position="none") +
geom_boxplot(fill = "#ffff00") + facet_wrap( ~ file_extension)
ggplotly(p, tooltip = "text")
rm(p)
Como nossas perguntas não são relacionadas à diferenças entre as linguagens, apenas o que nos interessa é a distribuição de cada uma separadamente. Porém, com os boxplots gerados, percebemos que os usuários editam mais arquivos em C++ do que em C#. Além disso, verificamos que há valores discrepantes, por esse motivo, iremos utilizar a mediana nos nossos experimentos.
Há diferença significativa na quantidade de commits da linguagem C# no mês de janeiro de 2016 e 2017?
Primeiro, filtramos os dados de acordo com o nosso interesse (janeiro de 2016 e janeiro de 2017).
dados_2016 <- dados_cs %>% filter(the_month == "1") %>% filter(the_year == "2016")
dados_2017 <- dados_cs %>% filter(the_month == "1") %>% filter(the_year == "2017")
Agora podemos realizar os testes de permutação de modo a implementar nosso teste de hipóteses.
permutationTest2(data = dados_2016, statistic = median(users), data2 = dados_2017)
Call:
permutationTest2(data = dados_2016, statistic = median(users),
data2 = dados_2017)
Replications: 9999
Two samples, sample sizes are 31 31
Summary Statistics for the difference between samples 1 and 2:
Observed Mean Alternative PValue
median(users): dados_2016-dados_2017 -60 0.4058406 two.sided 0.0302
De acordo com o teste de hipóteses, o p-valor é igual a 0.0302. Dessa forma, significa que há apenas uma probabilidade de 3% de se observar uma diferença significativa na quantidade de commits entre os meses de janeiro de 2016 e 2017. Como essa probabilidade é muito pequena, rejeitamos a hipótese nula. Ao comparar esse resultado com o obtido utilizando IC, obsevamos que o resultado obtido foi o mesmo, já que não podemos afirmar que há diferença.
E durante os meses de janeiro de 2016 e 2017 há variação na quantidade de commits por dia?
p =
dados_cs %>%
filter(the_year == "2017") %>%
filter(the_month == "1") %>%
ggplot(aes(x=month_day,
y=users,
text = paste("Dia:",month_day,
"\nQuantidade de Usuários:",
users))) +
labs(y = "Quantidade de usuários", x = "Dia")+
theme(legend.position="none") +
geom_bar(stat = 'identity', fill = "#33ccff") + facet_wrap( ~ file_extension)
ggplotly(p, tooltip = "text")
rm(p)
Há variação, mas ela acontece entre intervalos de 5 dias, ou seja, esses dias devem ser nos fins de semana, os outros dias mantem a quantidade de commits em uma pequena faixa de intervalo (1114 e 1313 commits).
Há diferença na popularidade da linguagem C++ durante períodos de férias e períodos de aulas?
Para essa pergunta, vamos considerar períodos de férias os mêses de janeiro, junho, julho e dezembro.
dados_ferias <- dados_cpp %>% filter(the_month %in% c("1", "6", "7", "12"))
dados_aulas <- dados_cpp %>% filter(the_month %in% c("2", "3", "4", "5", "8", "9", "10", "11"))
Agora podemos realizar os testes de permutação de modo a implementar nosso teste de hipóteses.
permutationTest2(data = dados_ferias, statistic = median(users), data2 = dados_aulas)
Call:
permutationTest2(data = dados_ferias, statistic = median(users),
data2 = dados_aulas)
Replications: 9999
Two samples, sample sizes are 154 342
Summary Statistics for the difference between samples 1 and 2:
Observed Mean Alternative PValue
median(users): dados_ferias-dados_aulas 2 0.649565 two.sided 0.945
De acordo com o teste de hipóteses, o p-valor é igual a 0.945. Dessa forma, significa que há probabilidade de 94% de se observar uma diferença de significativa na quantidade de commits entre o período de férias e o período de aulas. Como essa probabilidade é grande, aceitamos a hipótese nula. Ao comparar esse resultado com o obtido utilizando IC, obsevamos que o resultado foi diferente, o que é estranho, portanto, acredito que houve um erro ao fazer o calculo do IC.
Qual a distribuição dos dados durante o período de férias?
p =
dados_cpp %>%
filter(the_year == "2016") %>%
filter(the_month %in% c("1", "6", "7", "12")) %>%
ggplot(aes(x=month_day,
y=users,
text = paste("Dia:",month_day,
"\nQuantidade de Usuários:",
users))) +
labs(y = "Quantidade de usuários", x = "Dia")+
theme(legend.position="none") +
geom_bar(stat = 'identity', fill = "#0066ff") + facet_wrap( ~ the_month)
ggplotly(p, tooltip = "text")
rm(p)
A quantidade de commits apenas varia nos fins de semana, onde a quantidade é menor, mas nos outros período essa quantidade se mantem em uma pequena faixa.
LS0tCnRpdGxlOiAiRGFkb3MgZGUgY29tbWl0cyBubyBnaXRodWIiCmRhdGU6IDIwMTgtMDctMjIKYXV0aG9yOiAiTWFpbmFyYSBDYXZhbGNhbnRpIGRlIEZhcmlhcyIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICBkZl9wcmludDogcGFnZWQKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKLS0tCgojIyBJbnRyb2R1w6fDo28KCjxwPk5lc3NlIHJlbGF0w7NyaW8gc2Vyw6EgYXBsaWNhZG8gdGVzdGVzIGRlIGhpcMOzdGVzZSBwYXJhIHF1ZSBwb3NzYW1vcyByZXNwb25kZXIgYWxndW1hcyBwZXJndW50YXMgKihlc3NhcyBtZXNtYXMgcGVyZ3VudGFzIGZvcmFtIHJlc3BvbmRpZGFzIHV0aWxpemFuZG8gSUNzIFthcXVpXShodHRwczovL2dpdGh1Yi5jb20vTWFpbmFyYS9kYWRvcy1naXRodWIvYmxvYi9tYXN0ZXIvcmVwb3J0cy9ub3Zhcy1wZXJndW50YXMuUm1kKSkqLiA8L2JyPgo8cD5BbnRlcyBkZSB2ZXJpZmljYXIgb3MgcmVzdWx0YWRvcyBvYnRpZG9zLCDDqSBpbXBvcnRhbnRlIHF1ZSBvIGxlaXRvciBzYWliYSBvIHF1ZSBzaWduaWZpY2EgZSBjb21vIGludGVycHJldGFyIG8gKnAtdmFsb3IqLiBPICpwLXZhbG9yKiDDqSBhIHByb2JhYmlsaWRhZGUgZGUgc2Ugb2J0ZXIgdW1hIGVzdGF0w61zdGljYSBkZSB0ZXN0ZSBpZ3VhbCBvdSBtYWlzIGV4dHJlbWEgcXVlIGFxdWVsYSBvYnNlcnZhZGEgZW0gdW1hIGFtb3N0cmEgc29iIGEgaGlww7N0aXNlIG51bGEsIG91IHNlamEsIHVtICpwLXZhbG9yKiBwZXF1ZW5vIHNpZ25pZmljYSBxdWUgYSBwcm9iYWJpbGlkYWRlIGRlIG9idGVyIHVtIHZhbG9yIGRhIGVzdGF0w61zdGljYSBkZSB0ZXN0ZSBjb21vIG8gb2JzZXJ2YWRvIMOpIG11aXRvIGltcHJvdsOhdmVsLCBsZXZhbmRvIGFzc2ltIMOgIHJlamVpw6fDo28gZGEgaGlww7N0ZXNlIG51bGEuIDwvYnI+CjxwPkVtIHVtIHRlc3RlIGNsw6Fzc2ljbyBkZSBoaXDDs3Rlc2VzLCBzw6NvIGRlZmluaWRhcyBkdWFzIGhpcMOzdGVzZXMsIGEgbnVsYSAoSDApIGUgYSBhbHRlcm5hdGl2YSAoSDEpLiBFbSBtdWl0YXMgYXBsaWNhw6fDtWVzIGRhIGVzdGF0w61zdGljYSwgY29udmVuY2lvbmEtc2UgZGVmaW5pciBhIGhpcMOzdGVzZSBhbHRlcm5hdGl2YSBjb21vIGEgaGlww7N0ZXNlIGZvcm11bGFkYSBwZWxvIHBlc3F1aXNhZG9yLCBlbnF1YW50byBhIGhpcMOzdGVzZSBudWxhIMOpIG8gc2V1IGNvbXBsZW1lbnRvLiBBIHByaW5jw61waW8sIGEgaGlww7N0ZXNlIG51bGEgw6kgY29uc2lkZXJhZGEgYSB2ZXJkYWRlaXJhLiA8L2JyPgoKPHA+Tm8gZmltIGRlc3NlIHJlbGF0w7NyaW8sIHNlcsOjbyBjb21wYXJhZG9zIG9zIHJlc3VsdGFkb3Mgb2J0aWRvcyBhcXVpIGUgb3MgdXRpbGl6YW5kbyBJQ3MuIDwvYnI+CjxwPkFzc2ltIGNvbW8gbm8gKltDUDNdKGh0dHBzOi8vZ2l0aHViLmNvbS9NYWluYXJhL2RhZG9zLWdpdGh1Yi9ibG9iL21hc3Rlci9yZXBvcnRzL25vdmFzLXBlcmd1bnRhcy5SbWQpKiwgZXN0ZSByZWxhdMOzcmlvIHRlbSBjb21vIG9iamV0aXZvIGFuYWxpc2FyIGRhZG9zIGRlIGNvbW1pdHMgbm8gZ2l0aHViLiBVdGlsaXphcmVtb3MgdW1hIGFtb3N0cmEgZGUgZGFkb3MgZGEgYXRpdmlkYWRlIGdsb2JhbCBkbyBnaXRodWIgZW50cmUgbyBwZXLDrW9kbyBkZSAwMS8yMDE2IGUgMDUvMjAxNy4gQXMgbGluZ3VhZ2VucyBxdWUgdmFtb3MgYW5hbGlzYXIgc2Vyw6NvICpDKysqIGUgKkMjKiAoZHVhcyBkYXMgbGluZ3VhZ2VucyBtYWlzIHBvcHVsYXJlcyBlbnRyZSBvcyBwcm9ncmFtYWRvcmVzKS4gCgpgYGB7ciBzZXR1cCwgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoaGVyZSkKbGlicmFyeShwbG90bHkpCmxpYnJhcnkocmVzYW1wbGUsIHF1aWV0bHkgPSBUUlVFKQpgYGAKClByaW1laXJvLCBzZXLDoSBmZWl0YSBhIGltcG9ydGHDp8OjbyBkb3MgZGFkb3MgasOhIGNvbSBhcyBsaW5ndWFnZW5zIGRlIGludGVyZXNzZSBmaWx0cmFkYXMuIEFzIHZhcmnDoXZlaXMgcXVlIGlyZW1vcyB1dGlsaXphciBzZXLDo28gKnRoZV95ZWFyKihvIGFubyByZWZlcmVudGUgYW9zIGNvbW1pdHMpLCAqdGhlX21vbnRoKiAobyBtw6pzIHJlZmVyZW50ZSBhb3MgY29tbWl0cykgZSAqdXNlcnMqIChxdWFudGlkYWRlIGRlIHVzdcOhcmlvcyBxdWUgZmV6IGNvbW1pdHMpLgoKYGBge3J9CmRhZG9zX2dpdGh1YiA9IHJlYWRfY3N2KGhlcmUoImRhdGEvZ2l0aHViLXVzZXJzLWNvbW1pdHRpbmctZmlsZXR5cGVzLmNzdiIpLAogICAgICAgICAgICAgICAgICAgICAgICBwcm9ncmVzcyA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICBjb2xfdHlwZXMgPSBjb2xzKGZpbGVfZXh0ZW5zaW9uID0gY29sX2NoYXJhY3RlcigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb250aF9kYXkgPSBjb2xfaW50ZWdlcigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVfbW9udGggPSBjb2xfaW50ZWdlcigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVfeWVhciA9IGNvbF9pbnRlZ2VyKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVzZXJzID0gY29sX2ludGVnZXIoKSkpICU+JSAKICBmaWx0ZXIoZmlsZV9leHRlbnNpb24gJWluJSBjKCJjcHAiLCAiY3MiKSkKCgpkYWRvc19jcyA9IGRhZG9zX2dpdGh1YiAlPiUgZmlsdGVyKGZpbGVfZXh0ZW5zaW9uID09ICJjcyIpCmRhZG9zX2NwcCA9IGRhZG9zX2dpdGh1YiAlPiUgZmlsdGVyKGZpbGVfZXh0ZW5zaW9uID09ICJjcHAiKQoKYGBgCgpBbnRlcyBkZSByZXNwb25kZXIgYWxndW1hcyBwZXJndW50YXMsIHZhbW9zIGRhciB1bWEgb2xoYWRhIG5hIGxpbmhhIGRvIHRlbXBvIGRhcyBkdWFzIGxpbmd1YWdlbnMuCgojIyMjIEFubyBkZSAyMDE2CgpgYGB7cn0KcCA9CiAgZGFkb3NfZ2l0aHViICU+JSAKICBmaWx0ZXIodGhlX3llYXIgPT0gIjIwMTYiKSAlPiUgCiAgZ2dwbG90KGFlcyh4PXRoZV9tb250aCwgCiAgICAgICAgICAgICB5PXVzZXJzLAogICAgICAgICAgICAgdGV4dCA9IHBhc3RlKCJNw6pzOiIsdGhlX21vbnRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIlxuUXVhbnRpZGFkZSBkZSBVc3XDoXJpb3M6IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVzZXJzKSkpICsKICAgICBsYWJzKHkgPSAiUXVhbnRpZGFkZSBkZSB1c3XDoXJpb3MiLCB4ID0gIk3DqnMiKSsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpICsKICBnZW9tX2JveHBsb3QoZmlsbCA9ICIjZTk5NzkwIikgKyBmYWNldF93cmFwKCB+IGZpbGVfZXh0ZW5zaW9uKQpnZ3Bsb3RseShwLCB0b29sdGlwID0gInRleHQiKQoKcm0ocCkKYGBgCgojIyMjIEFubyBkZSAyMDE3CmBgYHtyfQpwID0KICBkYWRvc19naXRodWIgJT4lIAogIGZpbHRlcih0aGVfeWVhciA9PSAiMjAxNyIpICU+JSAKICBnZ3Bsb3QoYWVzKHg9dGhlX21vbnRoLCAKICAgICAgICAgICAgIHk9dXNlcnMsCiAgICAgICAgICAgICB0ZXh0ID0gcGFzdGUoIk3DqnM6Iix0aGVfbW9udGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiXG5RdWFudGlkYWRlIGRlIFVzdcOhcmlvczoiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlcnMpKSkgKwogICAgIGxhYnMoeSA9ICJRdWFudGlkYWRlIGRlIHVzdcOhcmlvcyIsIHggPSAiTcOqcyIpKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgKwogIGdlb21fYm94cGxvdChmaWxsID0gIiNmZmZmMDAiKSArIGZhY2V0X3dyYXAoIH4gZmlsZV9leHRlbnNpb24pCmdncGxvdGx5KHAsIHRvb2x0aXAgPSAidGV4dCIpCgpybShwKQpgYGAKCkNvbW8gbm9zc2FzIHBlcmd1bnRhcyBuw6NvIHPDo28gcmVsYWNpb25hZGFzIMOgIGRpZmVyZW7Dp2FzIGVudHJlIGFzIGxpbmd1YWdlbnMsIGFwZW5hcyBvIHF1ZSBub3MgaW50ZXJlc3NhIMOpIGEgZGlzdHJpYnVpw6fDo28gZGUgY2FkYSB1bWEgc2VwYXJhZGFtZW50ZS4gUG9yw6ltLCBjb20gb3MgYm94cGxvdHMgZ2VyYWRvcywgcGVyY2ViZW1vcyBxdWUgb3MgdXN1w6FyaW9zIGVkaXRhbSBtYWlzIGFycXVpdm9zIGVtICpDKysqIGRvIHF1ZSBlbSAqQyMqLiBBbMOpbSBkaXNzbywgdmVyaWZpY2Ftb3MgcXVlIGjDoSB2YWxvcmVzIGRpc2NyZXBhbnRlcywgcG9yIGVzc2UgbW90aXZvLCBpcmVtb3MgdXRpbGl6YXIgYSBtZWRpYW5hIG5vcyBub3Nzb3MgZXhwZXJpbWVudG9zLgoKIyMjSMOhIGRpZmVyZW7Dp2Egc2lnbmlmaWNhdGl2YSBuYSBxdWFudGlkYWRlIGRlIGNvbW1pdHMgZGEgbGluZ3VhZ2VtIEMjIG5vIG3DqnMgZGUgamFuZWlybyBkZSAyMDE2IGUgMjAxNz8KClByaW1laXJvLCBmaWx0cmFtb3Mgb3MgZGFkb3MgZGUgYWNvcmRvIGNvbSBvIG5vc3NvIGludGVyZXNzZSAoamFuZWlybyBkZSAyMDE2IGUgamFuZWlybyBkZSAyMDE3KS4KCmBgYHtyfQpkYWRvc18yMDE2IDwtIGRhZG9zX2NzICU+JSAgZmlsdGVyKHRoZV9tb250aCA9PSAiMSIpICU+JSBmaWx0ZXIodGhlX3llYXIgPT0gIjIwMTYiKQoKCmRhZG9zXzIwMTcgPC0gZGFkb3NfY3MgJT4lICBmaWx0ZXIodGhlX21vbnRoID09ICIxIikgJT4lIGZpbHRlcih0aGVfeWVhciA9PSAiMjAxNyIpCgpgYGAKCkFnb3JhIHBvZGVtb3MgcmVhbGl6YXIgb3MgdGVzdGVzIGRlIHBlcm11dGHDp8OjbyBkZSBtb2RvIGEgaW1wbGVtZW50YXIgbm9zc28gdGVzdGUgZGUgaGlww7N0ZXNlcy4KCmBgYHtyfQpwZXJtdXRhdGlvblRlc3QyKGRhdGEgPSBkYWRvc18yMDE2LCBzdGF0aXN0aWMgPSBtZWRpYW4odXNlcnMpLCBkYXRhMiA9IGRhZG9zXzIwMTcpCmBgYAoKRGUgYWNvcmRvIGNvbSBvIHRlc3RlIGRlIGhpcMOzdGVzZXMsIG8gKnAtdmFsb3IqIMOpIGlndWFsIGEgMC4wMzAyLiBEZXNzYSBmb3JtYSwgc2lnbmlmaWNhIHF1ZSBow6EgYXBlbmFzIHVtYSBwcm9iYWJpbGlkYWRlIGRlIDMlIGRlIHNlIG9ic2VydmFyIHVtYSBkaWZlcmVuw6dhIHNpZ25pZmljYXRpdmEgbmEgcXVhbnRpZGFkZSBkZSBjb21taXRzIGVudHJlIG9zIG1lc2VzIGRlIGphbmVpcm8gZGUgMjAxNiBlIDIwMTcuIENvbW8gZXNzYSBwcm9iYWJpbGlkYWRlIMOpIG11aXRvIHBlcXVlbmEsIHJlamVpdGFtb3MgYSBoaXDDs3Rlc2UgbnVsYS48L2J0PgpBbyBjb21wYXJhciBlc3NlIHJlc3VsdGFkbyBjb20gbyBvYnRpZG8gdXRpbGl6YW5kbyBJQywgb2JzZXZhbW9zIHF1ZSBvIHJlc3VsdGFkbyBvYnRpZG8gZm9pIG8gbWVzbW8sIGrDoSBxdWUgbsOjbyBwb2RlbW9zIGFmaXJtYXIgcXVlIGjDoSBkaWZlcmVuw6dhLgoKIyMjI0UgZHVyYW50ZSBvcyBtZXNlcyBkZSBqYW5laXJvIGRlIDIwMTYgZSAyMDE3IGjDoSB2YXJpYcOnw6NvIG5hIHF1YW50aWRhZGUgZGUgY29tbWl0cyBwb3IgZGlhPwoKYGBge3J9CnAgPQogIGRhZG9zX2NzICU+JSAKICBmaWx0ZXIodGhlX3llYXIgPT0gIjIwMTciKSAlPiUKICBmaWx0ZXIodGhlX21vbnRoID09ICIxIikgJT4lIAogIGdncGxvdChhZXMoeD1tb250aF9kYXksIAogICAgICAgICAgICAgeT11c2VycywKICAgICAgICAgICAgIHRleHQgPSBwYXN0ZSgiRGlhOiIsbW9udGhfZGF5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIlxuUXVhbnRpZGFkZSBkZSBVc3XDoXJpb3M6IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVzZXJzKSkpICsKICAgICBsYWJzKHkgPSAiUXVhbnRpZGFkZSBkZSB1c3XDoXJpb3MiLCB4ID0gIkRpYSIpKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknLCBmaWxsID0gIiMzM2NjZmYiKSArIGZhY2V0X3dyYXAoIH4gZmlsZV9leHRlbnNpb24pCmdncGxvdGx5KHAsIHRvb2x0aXAgPSAidGV4dCIpCgpybShwKQpgYGAKCkjDoSB2YXJpYcOnw6NvLCBtYXMgZWxhIGFjb250ZWNlIGVudHJlIGludGVydmFsb3MgZGUgNSBkaWFzLCBvdSBzZWphLCBlc3NlcyBkaWFzIGRldmVtIHNlciBub3MgZmlucyBkZSBzZW1hbmEsIG9zIG91dHJvcyBkaWFzIG1hbnRlbSBhIHF1YW50aWRhZGUgZGUgY29tbWl0cyBlbSB1bWEgcGVxdWVuYSBmYWl4YSBkZSBpbnRlcnZhbG8gKDExMTQgZSAxMzEzIGNvbW1pdHMpLgoKIyMjSMOhIGRpZmVyZW7Dp2EgbmEgcG9wdWxhcmlkYWRlIGRhIGxpbmd1YWdlbSBDKysgZHVyYW50ZSBwZXLDrW9kb3MgZGUgZsOpcmlhcyBlIHBlcsOtb2RvcyBkZSBhdWxhcz8KClBhcmEgZXNzYSBwZXJndW50YSwgdmFtb3MgY29uc2lkZXJhciBwZXLDrW9kb3MgZGUgZsOpcmlhcyBvcyBtw6pzZXMgZGUgamFuZWlybywganVuaG8sIGp1bGhvIGUgZGV6ZW1icm8uCgpgYGB7cn0KZGFkb3NfZmVyaWFzIDwtIGRhZG9zX2NwcCAlPiUgIGZpbHRlcih0aGVfbW9udGggJWluJSBjKCIxIiwgIjYiLCAiNyIsICIxMiIpKSAKCmRhZG9zX2F1bGFzIDwtIGRhZG9zX2NwcCAlPiUgIGZpbHRlcih0aGVfbW9udGggJWluJSBjKCIyIiwgIjMiLCAiNCIsICI1IiwgIjgiLCAiOSIsICIxMCIsICIxMSIpKQoKYGBgCgpBZ29yYSBwb2RlbW9zIHJlYWxpemFyIG9zIHRlc3RlcyBkZSBwZXJtdXRhw6fDo28gZGUgbW9kbyBhIGltcGxlbWVudGFyIG5vc3NvIHRlc3RlIGRlIGhpcMOzdGVzZXMuCgpgYGB7cn0KcGVybXV0YXRpb25UZXN0MihkYXRhID0gZGFkb3NfZmVyaWFzLCBzdGF0aXN0aWMgPSBtZWRpYW4odXNlcnMpLCBkYXRhMiA9IGRhZG9zX2F1bGFzKQpgYGAKRGUgYWNvcmRvIGNvbSBvIHRlc3RlIGRlIGhpcMOzdGVzZXMsIG8gKnAtdmFsb3IqIMOpIGlndWFsIGEgMC45NDUuIERlc3NhIGZvcm1hLCBzaWduaWZpY2EgcXVlIGjDoSBwcm9iYWJpbGlkYWRlIGRlIDk0JSBkZSBzZSBvYnNlcnZhciB1bWEgZGlmZXJlbsOnYSBkZSBzaWduaWZpY2F0aXZhIG5hIHF1YW50aWRhZGUgZGUgY29tbWl0cyBlbnRyZSBvIHBlcsOtb2RvIGRlIGbDqXJpYXMgZSBvIHBlcsOtb2RvIGRlIGF1bGFzLiBDb21vIGVzc2EgcHJvYmFiaWxpZGFkZSDDqSBncmFuZGUsIGFjZWl0YW1vcyBhIGhpcMOzdGVzZSBudWxhLjwvYnQ+CkFvIGNvbXBhcmFyIGVzc2UgcmVzdWx0YWRvIGNvbSBvIG9idGlkbyB1dGlsaXphbmRvIElDLCBvYnNldmFtb3MgcXVlIG8gcmVzdWx0YWRvIGZvaSBkaWZlcmVudGUsIG8gcXVlIMOpIGVzdHJhbmhvLCBwb3J0YW50bywgYWNyZWRpdG8gcXVlIGhvdXZlIHVtIGVycm8gYW8gZmF6ZXIgbyBjYWxjdWxvIGRvIElDLgoKIyMjI1F1YWwgYSBkaXN0cmlidWnDp8OjbyBkb3MgZGFkb3MgZHVyYW50ZSBvIHBlcsOtb2RvIGRlIGbDqXJpYXM/CgpgYGB7cn0KcCA9CiAgZGFkb3NfY3BwICU+JSAKICBmaWx0ZXIodGhlX3llYXIgPT0gIjIwMTYiKSAlPiUKICBmaWx0ZXIodGhlX21vbnRoICVpbiUgYygiMSIsICI2IiwgIjciLCAiMTIiKSkgJT4lIAogIGdncGxvdChhZXMoeD1tb250aF9kYXksIAogICAgICAgICAgICAgeT11c2VycywKICAgICAgICAgICAgIHRleHQgPSBwYXN0ZSgiRGlhOiIsbW9udGhfZGF5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIlxuUXVhbnRpZGFkZSBkZSBVc3XDoXJpb3M6IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVzZXJzKSkpICsKICAgICBsYWJzKHkgPSAiUXVhbnRpZGFkZSBkZSB1c3XDoXJpb3MiLCB4ID0gIkRpYSIpKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknLCBmaWxsID0gIiMwMDY2ZmYiKSArIGZhY2V0X3dyYXAoIH4gdGhlX21vbnRoKQpnZ3Bsb3RseShwLCB0b29sdGlwID0gInRleHQiKQoKcm0ocCkKYGBgCgpBIHF1YW50aWRhZGUgZGUgY29tbWl0cyBhcGVuYXMgdmFyaWEgbm9zIGZpbnMgZGUgc2VtYW5hLCBvbmRlIGEgcXVhbnRpZGFkZSDDqSBtZW5vciwgbWFzIG5vcyBvdXRyb3MgcGVyw61vZG8gZXNzYSBxdWFudGlkYWRlIHNlIG1hbnRlbSBlbSB1bWEgcGVxdWVuYSBmYWl4YS4K